#include "qdeviceview.h"

#include "qsoftcore.h"
#include "qbaseitemdelegate.h"

#include "../device/qbasedefine.h"
#include "../device/qdevicemanager.h"

#include <QMenu>
#include <QContextMenuEvent>

#include <QHeaderView>
#include <QItemDelegate>
#include <QStyleOptionViewItemV3>
#include <QPainter>

class QDeviceDelegate: public QBaseItemDelegate
{
public :
    QDeviceDelegate(QDeviceView* view):m_view(view){}
    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
protected:
    QDeviceView     *m_view;
};

void QDeviceDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QStyleOptionViewItemV3 opt=option;
    QColor c;
    QTreeWidgetItem *item=m_view->itemFromIndex(index);
    if(item->text(6)==tr("Online"))
    {
        c=QColor(BACKGROUND_COLOR);
        if(opt.features & QStyleOptionViewItemV2::Alternate)
        {
            c=c.lighter(112);
        }
    }
    else
    {

        c=QColor(255,0,0);
    }

    painter->fillRect(option.rect,c);
    opt.state &=~ QStyle::State_HasFocus;
    QItemDelegate::paint(painter,opt,index);
}

QDeviceView::QDeviceView(QWidget *parent) :
    QTreeWidget(parent)
{
    this->setFrameStyle(QFrame::NoFrame);
    this->setAlternatingRowColors(true);
    header()->setMovable(false);
    this->setRootIsDecorated(false);
    setItemDelegate(new QDeviceDelegate(this));


    QStringList list;
    list<<tr("ID")<<tr("Project Name")
       <<tr("System Type")<<tr("Soft Type")
      <<tr("Device Version")<<tr("Device IP")<<tr("Device Status");

    this->setHeaderLabels(list);

    init();
}

void QDeviceView::init()
{
    QDeviceManager *manager=QSoftCore::get_core()->get_device_manager();
    QList<tagDeviceInfo*> list=manager->get_devices();

    tagDeviceInfo* device;

    foreach(tagDeviceInfo *info,list)
    {
        QTreeWidgetItem *item=new QTreeWidgetItem(this);
        item->setText(0,info->m_uuid);
        item->setToolTip(0,info->m_uuid);
        item->setText(1,info->m_project_name);
        item->setText(2,info->m_device_type);
        item->setText(3,info->m_soft_status);
        item->setText(4,info->m_soft_version);
        item->setText(5,int_to_ip(info->m_device_ip));
        item->setText(6,tr("Online"));

        device=new tagDeviceInfo;
        *device=*info;
        m_item_to_device.insert(item,device);
        m_device_to_item.insert(device,item);
        m_uuid_to_item.insert(device->m_uuid,item);
    }

    connect(manager,SIGNAL(device_online(tagDeviceInfo*)),this,SLOT(device_online(tagDeviceInfo*)));
    connect(manager,SIGNAL(device_offline(QString)),this,SLOT(device_offline(QString)));
    connect(this,SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),this,SLOT(select_device()));
}

QString QDeviceView::int_to_ip(uint ip)
{
    QString ret;
    ret.sprintf("%03d.%03d.%03d.%03d",(ip>>24)&0xff,
                (ip>>16)&0xff,(ip>>8)&0xff,ip&0xff);

    return ret;
}

void QDeviceView::device_online(tagDeviceInfo *device)
{
    if(m_uuid_to_item.keys().contains(device->m_uuid))
    {
        QTreeWidgetItem *item=m_uuid_to_item.value(device->m_uuid);
        tagDeviceInfo* in=m_item_to_device.value(item);
        *in=*device;
        item->setText(0,device->m_uuid);
        item->setToolTip(0,device->m_uuid);
        item->setText(1,device->m_project_name);
        item->setText(2,device->m_device_type);
        item->setText(3,device->m_soft_status);
        item->setText(4,device->m_soft_version);
        item->setText(5,int_to_ip(device->m_device_ip));
        item->setText(6,tr("Online"));
        for(int i=0;i<7;i++)
        {
            this->update(indexFromItem(item,i));
        }
        return;
    }
    QTreeWidgetItem *item=new QTreeWidgetItem(this);
    item->setText(0,device->m_uuid);
    item->setToolTip(0,device->m_uuid);
    item->setText(1,device->m_project_name);
    item->setText(2,device->m_device_type);
    item->setText(3,device->m_soft_status);
    item->setText(4,device->m_soft_version);
    item->setText(5,int_to_ip(device->m_device_ip));
    item->setText(6,tr("Online"));
    for(int i=0;i<7;i++)
    {
        this->update(indexFromItem(item,i));
    }
    tagDeviceInfo* info=new tagDeviceInfo;
    *info=*device;
    m_item_to_device.insert(item,info);
    m_device_to_item.insert(info,item);
    m_uuid_to_item.insert(info->m_uuid,item);
}

void QDeviceView::device_offline(const QString &uuid)
{
    QTreeWidgetItem* item=m_uuid_to_item.value(uuid);
    if(item!=NULL)
    {
        item->setText(6,tr("Offline"));
    }
}

void QDeviceView::contextMenuEvent(QContextMenuEvent *e)
{
    QMenu menu;
    menu.addAction(tr("Select Device"),this,SLOT(select_device()));
    menu.addAction(tr("Clear Offline"),this,SLOT(clear_offline()));
    menu.exec(e->globalPos());
}

void QDeviceView::clear_offline()
{
    QMapIterator<QTreeWidgetItem*,tagDeviceInfo*> it(m_item_to_device);

    QList<QTreeWidgetItem*> list;

    while(it.hasNext())
    {
        it.next();
        if(it.key()->text(6)==tr("Offline"))
        {
            list.append(it.key());
        }
    }

    foreach(QTreeWidgetItem* item,list)
    {
        tagDeviceInfo* info=m_item_to_device.value(item);
        m_item_to_device.remove(item);
        m_device_to_item.remove(info);
        m_uuid_to_item.remove(info->m_uuid);
        delete info;
        delete item;
    }
}

void QDeviceView::select_device()
{
    QTreeWidgetItem* item=currentItem();
    if(item==NULL)
    {
        return;
    }

    QMapIterator<int,QString>   it(m_enabled);

    while(it.hasNext())
    {
        it.next();
        if(item->text(it.key())==it.value())
        {
            return;
        }
    }

    select(m_item_to_device.value(item));
}

void QDeviceView::set_enabled(const QMap<int, QString> &enabled)
{
    m_enabled=enabled;
}
